﻿#region License
// /* **************************************************************
// * Copyright (C) intex Consulting GmbH - All Rights Reserved    *
// *--------------------------------------------------------------*
// * Unauthorized copying of this file, via any medium is         *
// * strictly prohibited                                          *
// *--------------------------------------------------------------*
// * Proprietary and confidential                                 *
// *--------------------------------------------------------------*
// * Dissasembling/modifications strictly prohibited!             *
// ***************************************************************/
#endregion

using System.Text;
using ComHlp.Exceptions;
using NLog;

namespace ComHlp.Classes
{
    public class BsResponseHelper
    {
        private readonly Logger _log = LogManager.GetCurrentClassLogger();

        /// <summary> insert passed value into passed response at position for fieldlength </summary>
        /// <param name="sbResponse"></param>
        /// <param name="value"></param>
        /// <param name="bytePos"></param>
        /// <param name="byteFieldLength"></param>
        /// <returns></returns>
        /// <exception cref="EncodingException">Condition.</exception>
        public int InsertValueIntoBsResponse(StringBuilder sbResponse, string value, int bytePos, int byteFieldLength)
        {
            // general cut fix.. we should not insert things which are longer than the field...
            if (value.Length > byteFieldLength)
            {
                value = value.Substring(0, byteFieldLength);
#if DEBUG
                _log.Debug($"Value to insert is longer than expected: {value} - field length: {byteFieldLength}");
#endif
            }

            // fill up in general
            string insertValue = value.PadRight(byteFieldLength);

            // utf8 checkup?
            if (ComStatics.UseUtf8)
            {
                //
                // strip down the value to insert to the necessary bytecount (==fieldlength)
                int insertValueByteCount = ComStatics.Encoder.GetByteCount(insertValue);
                if (insertValueByteCount > byteFieldLength)
                {
                    // we already noticed that we got more bytes than we should... so we try cutting one char less
                    int removeAtIndex = byteFieldLength;
                    while (insertValueByteCount > byteFieldLength)
                    {
                        if (removeAtIndex < 1)
                            throw new EncodingException($"Byte parsing problem with: {insertValue} - {sbResponse}");

                        insertValue = insertValue.Remove(--removeAtIndex);
                        // re-check bytecount
                        insertValueByteCount = ComStatics.Encoder.GetByteCount(insertValue);
                    }

                    // check if we have removed to much
                    while (insertValueByteCount < byteFieldLength)
                    {
                        insertValue = $"{insertValue} ";

                        // re-check bytecount
                        insertValueByteCount = ComStatics.Encoder.GetByteCount(insertValue);
                    }
                }

                //
                // now we need to analyze the length to cut from the response before inserting it (it may already contain utf8
                //   double/tripple byte characters)
                int cutLength = byteFieldLength;
                string originValue = sbResponse.ToString(bytePos, cutLength);
                int byteCount = ComStatics.Encoder.GetByteCount(originValue);
                if (byteCount > byteFieldLength)
                {
                    // we already noticed that we got more bytes than we should... so we try cutting one char less
                    while (byteCount > byteFieldLength)
                    {
                        if (cutLength < 1)
                            throw new EncodingException($"Byte parsing problem with: {insertValue} - {sbResponse}");

                        originValue = sbResponse.ToString(bytePos, --cutLength);

                        // re-check bytecount
                        byteCount = ComStatics.Encoder.GetByteCount(originValue);
                    }
                }

                // finally remove and insert
                sbResponse.Remove(bytePos, cutLength); //byteFieldLength cause of char cutting 
                sbResponse.Insert(bytePos, insertValue);
                var old = bytePos + insertValue.Length;
                return old;
            }

            // finally remove and insert
            sbResponse.Remove(bytePos, byteFieldLength);
            //sbResponse.Insert(pos, ResponseHelper.FormatBsResponseField(value, fieldLength));
            sbResponse.Insert(bytePos, insertValue);
            return bytePos + byteFieldLength;
        }
    }
}